home *** CD-ROM | disk | FTP | other *** search
- #import "PControl.h"
- #import "Plot3DView.h"
- #import <appkit/Control.h>
- #import <appkit/Matrix.h>
- #import <appkit/Application.h>
- #import <appkit/NXColorWell.h>
- #import <appkit/NXColorPanel.h>
- #import <appkit/ScrollView.h>
- #import <appkit/Text.h>
- #import <dpsclient/event.h>
- #import <dpsclient/psops.h>
- #import <appkit/color.h>
- #import <appkit/OpenPanel.h>
- #import <stdio.h>
- #import <math.h>
- #import <ctype.h>
- #include <libc.h>
- #import "Expression.h"
- #import "DensView.h"
-
- @implementation PControl
- -init
- {
- [super init];
- return self;
- }
-
- /* Called once by the Plot3DView to do initialization and pass pref pointer */
- -startup:(SetPref *)Pref
- {
- pref=Pref;
- /* display initial preferences settings */
- curPref=0;
- [symsel selectCellWithTag:pref[0].sym+1];
- [colorSel setColor:pref[0].color];
- equation=[equation docView];
- [equation setText:[pref[0].expr text]];
- /* make sure plot agrees with displayed min/max values */
- [d3View zoomTo:[minX floatValue] :[minY floatValue] :[maxX floatValue] :[maxY floatValue]];
- return self;
- }
-
- /* display preferences for a data set */
- -disPref:sender
- {
- curPref=[[sender selectedCell] tag];
- [symsel selectCellWithTag:pref[curPref].sym+1];
- [colorSel setColor:pref[curPref].color];
- if (pref[curPref].fileData==NULL) [ffSel selectCellWithTag:0];
- else [ffSel selectCellWithTag:1];
- [equation setText:[pref[curPref].expr text]];
- [d3View zoom:self];
- return self;
- }
-
- /* put preferences from screen into SetPref for curPref set */
- -stoPref:sender
- {
- char *tmp;
- int i,j,k;
- pref[curPref].sym=[[symsel selectedCell] tag]-1;
- pref[curPref].color=[colorSel color];
- tmp=malloc([equation textLength]+50);
- [equation getSubstring:tmp start:0 length:[equation textLength]+1];
- /* Fix equation for parsing */
- k=strlen(tmp);
- for (i=0; i<k; i++) {
- if (tmp[i]=='[') tmp[i]='(';
- if (tmp[i]==']') tmp[i]=')';
- if (isupper(tmp[i])) tmp[i]=tolower(tmp[i]);
- if ((tmp[i]=='+'||tmp[i]=='-')&&(isdigit(tmp[i+1])||tmp[i+1]=='.')) {
- for (j=k; j>i; j--) tmp[j+1]=tmp[j];
- tmp[i+1]=' ';
- k++;
- }
- }
-
- /* if the equation doesn't parse, set it to 0 */
- if (strlen(tmp)==0 ||
- [pref[curPref].expr parse:tmp]==0) {
- [equation setText:"0"];
- [pref[curPref].expr parse:"0"];
- }
- [d3View zoom:self];
- return self;
- }
-
- /* Read 3d data from a file and put it into the current data set */
- /* does NOT wait for an "OK" press, like other prefs */
- -readFile:sender
- {
- id panel;
- int i,c,cc=0;
- char s[80],sc[20];
- FILE *in;
- float x0,x1,y0,y1,f;
- Point *p;
-
- if (pref[curPref].fileData!=NULL) { free(pref[curPref].fileData); pref[curPref].
- fileData=NULL; }
-
- /* get a filespec from the user */
- panel=[[OpenPanel new] allowMultipleFiles:NO];
- if (![panel runModalForTypes:NULL]) {
- [ffSel selectCellWithTag:0];
- [equation setText:"0"];
- [pref[curPref].expr parse:"0"];
- return self;
- }
-
- /* if we can't open the file, go back to equation mode */
- in=fopen([panel filename],"r");
- if (fgets(s,80,in)==NULL) {
- [ffSel selectCellWithTag:0];
- [equation setText:"0"];
- [pref[curPref].expr parse:"0"];
- return self;
- }
-
- /* ignore leading # lines */
- while (s[0]=='#') { fgets(s,80,in); cc++; }
-
- /* accept either "x,y,z\n" or "x y z\n" files */
- strcpy(sc," %f , %f , %f");
- if (sscanf(s,sc,&x0,&y0,&f)!=3) {
- strcpy(sc," %f %f %f");
- if (sscanf(s,sc,&x0,&y0,&f)!=3) {
- [ffSel selectCellWithTag:0];
- [equation setText:"0"];
- [pref[curPref].expr parse:"0"];
- return self;
- }
- }
-
- /* count the number of points in the file */
- x1=x0; y1=y0;
- c=1;
- while (fscanf(in,sc,&f,&f,&f)==3) c++;
- rewind(in);
-
- /* 2nd pass, allocate memory and read data into array */
- p=pref[curPref].fileData=malloc(sizeof(Point)*c);
- pref[curPref].nfdata=c;
-
- for (i=0; i<cc; i++) fgets(s,80,in);
- for (i=0; i<c; i++) {
- fscanf(in,sc,&p[i].x,&p[i].y,&p[i].z);
- if (p[i].x>x1) x1=p[i].x;
- if (p[i].x<x0) x0=p[i].x;
- if (p[i].y>y1) y1=p[i].y;
- if (p[i].y<y0) y0=p[i].y;
- }
- if (pref[curPref].data!=NULL) free(pref[curPref].data);
- pref[curPref].data=malloc(sizeof(Point)*pref[curPref].nfdata);
- /* x0-=fabs(x0)/500.0+fabs(x1)/500.0;
- x1+=fabs(x0)/500.0+fabs(x1)/500.0;
- y0-=fabs(y0)/500.0+fabs(y1)/500.0;
- y1+=fabs(y0)/500.0+fabs(y1)/500.0; */
- [minX setFloatValue:x0];
- [minY setFloatValue:y0];
- [maxX setFloatValue:x1];
- [maxY setFloatValue:y1];
-
- /* equation is now used to modify data Z values, set initial formula for */
- /* z(x,y,z)=z. ie - for log plots you would enter "log(z)" */
- [equation setText:"z"];
- [pref[curPref].expr parse:"z"];
-
- /* update the display */
- [self setMinMax:self];
- [d3View zoom:self];
- return self;
- }
-
- /* return a data set to equation mode, free memory used by the file */
- -clearFile:sender
- {
- if (pref[curPref].fileData!=NULL) { free(pref[curPref].fileData); pref[curPref].fileData=NULL; }
- pref[curPref].nfdata=0;
-
- [equation setText:"0"];
- [pref[curPref].expr parse:"0"];
- [d3View zoom:self];
- return(self);
- }
-
- /* minz and maxz can be modified before returning, but currently aren't */
- -minmaxZ:(float *)minz :(float *)maxz
- {
- [minZ setFloatValue:*minz];
- [maxZ setFloatValue:*maxz];
- return self;
- }
-
- /* display new min/max values (does not inform the views of the change) */
- -setMM:(float)minx :(float)maxx :(float)miny :(float)maxy
- {
- [minX setFloatValue:minx];
- [minY setFloatValue:miny];
- [maxX setFloatValue:maxx];
- [maxY setFloatValue:maxy];
- return self;
- }
-
- /* Tell the Plot3DView and (indirectly) the DensView about new max/min vals */
- -setMinMax:sender
- {
- [d3View zoomTo:[minX floatValue] :[minY floatValue] :[maxX floatValue] :[maxY floatValue]];
- return self;
- }
-
- /* zoom in by a fixed amount */
- -zoomIn:sender
- {
- float x,y,x1,y1;
- x1=[maxX floatValue];
- x=[minX floatValue];
- y1=[maxY floatValue];
- y=[minY floatValue];
-
- [maxX setFloatValue:x1-(x1-x)/4.0];
- [minX setFloatValue:x+(x1-x)/4.0];
- [maxY setFloatValue:y1-(y1-y)/4.0];
- [minY setFloatValue:y+(y1-y)/4.0];
-
- [self setMinMax:self];
- [d3View zoom:self];
- return self;
- }
-
- /* zoom out by a fixed amount */
- -zoomOut:sender
- {
- float x,y,x1,y1;
- x1=[maxX floatValue];
- x=[minX floatValue];
- y1=[maxY floatValue];
- y=[minY floatValue];
-
- [maxX setFloatValue:x1+(x1-x)/4.0];
- [minX setFloatValue:x-(x1-x)/4.0];
- [maxY setFloatValue:y1+(y1-y)/4.0];
- [minY setFloatValue:y-(y1-y)/4.0];
-
- [self setMinMax:self];
- [d3View zoom:self];
- return self;
- }
-
- /* sent by DensView, min/max are from 0.0 to 1.0, not real units */
- -zoomTo:(float)minx :(float)miny :(float)maxx :(float)maxy
- {
- float x0,x1,y0,y1;
-
- x0=[minX floatValue];
- x1=[maxX floatValue];
- y0=[minY floatValue];
- y1=[maxY floatValue];
-
- [minX setFloatValue:x0+(x1-x0)*minx];
- [minY setFloatValue:y0+(y1-y0)*miny];
- [maxX setFloatValue:x0+(x1-x0)*maxx];
- [maxY setFloatValue:y0+(y1-y0)*maxy];
- [self setMinMax:self];
- [d3View zoom:self];
- return self;
- }
-
- /* update the density plot */
- -updDen
- {
- static float *densData=NULL;
- static int ndd=0;
- int k,n,i;
-
- n=[grid intValue];
- if (ndd<(n*n)) {
- if (densData!=NULL) free(densData);
- densData=malloc(n*n*sizeof(float));
- ndd=n*n;
- }
-
- if (pref[curPref].fileData==NULL) {
- for (k=0; k<pref[curPref].ndata; k++) densData[k]=pref[curPref].data[k].z;
- }
- else {
- for (k=0; k<(n*n); k++) densData[k]= -.5;
- for (k=0; k<pref[curPref].ndata; k++) {
- i=floor((pref[curPref].data[k].x+.5)*(float)n)+floor((pref[curPref].data[k].y+.5)*(float)n)*n;
- if (i>=0 && i<ndd) densData[i]=pref[curPref].data[k].z;
- }
- }
-
- if (pref[curPref].sym!= -1) [dView setData:n :n :densData :-.5 :.5];
- else [dView setData:0 :0 :NULL :-.5 :.5];
- return self;
- }
-
- @end
-